#pragma once

#include <common/include/base/type.h>

namespace Logic
{
	namespace Util
	{

// Utility class to read, write and manipulate the Windows Registry.
// Registry vocabulary primer: a "key" is like a folder, in which there
// are "values", which are <name, data> pairs, with an associated data type.
class CBdRegKey 
{
public:
	CBdRegKey();
	CBdRegKey(HKEY rootkey, const CStringW & strSubkey, REGSAM access);
	~CBdRegKey();

	BOOL Create(HKEY rootkey, const CStringW & strSubkey, REGSAM access);

	BOOL CreateWithDisposition(HKEY rootkey, const CStringW & strSubkey,
		DWORD * pDisposition, REGSAM access);

	BOOL Open(HKEY rootkey, const CStringW & strSubkey, REGSAM access);

	// Creates a subkey or open it if it already exists.
	BOOL CreateKey(const CStringW & strName, REGSAM access);

	// Opens a subkey
	BOOL OpenKey(const CStringW & strName, REGSAM access);

	VOID Close();

	DWORD ValueCount();

	// Determine the nth value's name.
	BOOL ReadName(INT nIndex, CStringW & strName);

	// True while the key is valid.
	BOOL Valid() const { return m_Key != NULL; }

	// Kill a key and everything that live below it; please be careful when using
	// it.
	BOOL DeleteKey(const CStringW & strName);

	// Deletes a single value within the key.
	BOOL DeleteValue(const CStringW & strName);

	BOOL ValueExists(const CStringW & strName);

	BOOL ReadValue(const CStringW & strName, VOID * pData, DWORD * pdwSize, DWORD* pdwType);
	BOOL ReadValue(const CStringW & strName, CStringW & strValue);
	BOOL ReadValueDW(const CStringW & strName, DWORD * pdwValue);

	BOOL WriteValue(const CStringW & strName, const VOID * pData, DWORD dwSize,
		DWORD dwType);
	BOOL WriteValue(const CStringW & strName, const CStringW & strValue);
	BOOL WriteValue(const CStringW & strName, DWORD dwValue);

	// Starts watching the key to see if any of its values have changed.
	// The key must have been opened with the KEY_NOTIFY access privelege.
	BOOL StartWatching();

	// If StartWatching hasn't been called, always returns false.
	// Otherwise, returns true if anything under the key has changed.
	// This can't be const because the |watch_event_| may be refreshed.
	BOOL HasChanged();

	// Will automatically be called by destructor if not manually called
	// beforehand.  Returns true if it was watching, false otherwise.
	BOOL StopWatching();

	inline BOOL IsWatching() const { return m_hWatchEvent != 0; }
	HANDLE WatchEvent() const { return m_hWatchEvent; }
	HKEY Handle() const { return m_Key; }

private:
	HKEY m_Key;  // The registry key being iterated.
	HANDLE m_hWatchEvent;

	DISALLOW_COPY_AND_ASSIGN(CBdRegKey);
};

	}
}